(function ($) {
jQuery.fn.extend({
lookup_form: function(options, _callback){
	var defaults = {
			  width				: 640
			, height			: 480
			, title				: "Dynamic Form"
			, type				: null //OPTIONS: null - show everything; create - show create screen; edit - show edit screen
			, context			: null
			, eventName			: "click"
			, data				: []
			, data_dropdown		: _build_data_dropdown
			, field				: _form_get_field
			, number_dropdown	: _build_number_dropdown
			, content_area		: null
			, _callback			: null
			, ui_groups			: []
			, link_buttons		: []
			, toolbar			: ["create", "update", "remove", "import", "export", "search", "clone"]
			, effect			: "blind"
			
			, use_dialog		: false
		};

	var table		= null;
	var old_data	= null; //SET THIS TO THE ROW VALUES FOR THE CURRENT ROW...IN-CASE NO PK IS SET.
	
	if (options.toolbar) defaults.toolbar = options.toolbar;
	options = $.extend(true, {}, defaults, options);
	
	if (_callback) options._callback = _callback;
	
	if (!(options.toolbar instanceof Array) || !options.toolbar) options.toolbar = [];
	
	if (!options.content_area){
		console.log("show in a dialog");
		options.use_dialog = true;
		options.content_area = $("<div>");
	} else {
		options.content_area = $(options.content_area);
	}
	
	if (options.eventName && options.eventName != null){
		$(this).unbind(options.eventName).bind(options.eventName, function(){show();});
	} else {
		show();
	}
	
	function show(){
		_create_with_data_grid();
	}
	
	function validate_data(data){
		var valid = true;
		
		//CHECK THAT REQUIRED FIELDS ARE PROVIDED
		var email_filter = /^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/;
		var number_filter = /^-?\d*\.?\d*$/;
		
		$(options.fields).each(function(){
			if (this.required == true){
				var val = data[this.name];
				
				if (typeof val === "undefined" ||
					null == val ||
					"" === val) {
					
					alert(this.title+" cannot be empty: >>"+val+"<< typeof:: "+typeof(val));
					valid = false;
					return
				}
				
				if (this.data_type.toLowerCase() == "email"){
					if (!email_filter.test(val)) {
						alert('Please provide a valid email address');
						valid = false;
					}
				}
				
				if (this.data_type.toLowerCase() == "number"){
					if (!number_filter.test(val)) {
						alert('Please provide a valid number');
						valid = false;
					}
				}
			}
		});
		
		return valid;
	}
	
	function _create_item(data, on_done){
		console.log("_create_item");
		
		var __create_item_ex = function(data){
			
			options.data.push(data);
			
			if (options._callback){
				options._callback(options.data);
			}
			
			if (typeof(on_done) == "function") on_done(data);
		}
		
		if (false == validate_data(data)){
			return;
		}
		if (options.ajax_url && options.ajax_url != null){
			var request = {
							  server_call		: options.server_call_create
							, ajax_url			: options.ajax_url
							, sql_table			: options.sql_table
							, async				: false
							, fields			: options.fields
							, data				: data
						};

			get_server_data(request, function(data){
				__create_item_ex(data);
			});
		} else {
			//NEED TO FAKE THE PRIMARY/AUTO-NUMBER FIELD
			//console.log("fake the auto-number");
			var pk = null;
			var max = 0;
			$(options.fields).each(function(){
				if (this.primary_key == true) pk = this.name;
			});
			$(options.data).each(function(){
				if (parseFloat(this[pk]) > max) max = parseFloat(this[pk]);
			});
			max++;
			data[pk] = max;
			//console.log("\t\tFAKE-ID: "+max);
			__create_item_ex(data);
		}
	}

	function _remove_item(on_done){
		var data = null;
		var cnt = table.find("tr td input[type=checkbox]:checked").length;

		if (cnt == 0){
			alert("Nothing was selected.");
			return;
		}
		else{
			var ret = confirm("Are you sure you want to remove the selected items?");
			if (false == ret) return;
		}

		table.find("tr td input[type=checkbox]:checked").each(function(){
			var row = $(this).parents("tr");
			
			ret = false;
			data = $(this).parents("tr").prop("row_data");
			$(options.fields).each(function(){
				if (typeof this.alias !== "undefined"){
					if (!(this.alias in data))
						data[this.alias] = data[this.name];
				}
			});

			//MAKE SURE WE DO NOT DELETE A RECORD THAT IS BEING REFERENCED
			var is_referenced = false;
			var msg = "";
			$(options.links).each(function(){
				var ref = this;
				//MAP FIELDS
				$(ref.mapping).each(function(){
					//DON'T FEEL LIKE DOING IT NOW.....22 JUNE 2013
					var src_field	= row.prop("row_data");
					var dest_field	= null;
					var map			= this;

					$(ref.reference.fields).each(function(){
						if (map.destination == this.name){
							dest_field = this;
						}
					});
					
					if (src_field != null && dest_field != null){
						//NOW ONLY COPY DATA THAT RELATES TO THE OPEN RECORD.
						$(ref.reference.data).each(function(){
							if (this[map.destination] == src_field[map.source]){
								msg += "Value is referenced in: "+ref.reference.sql_table+"\n";
								is_referenced = true;
							}
						});
					}
				});
			});
			
			if (true == is_referenced){
				alert(msg);
				return;
			}
			
			if (options.ajax_url && options.ajax_url != null){
				var request = {
								  ajax_url		: options.ajax_url
								, server_call	: options.server_call_remove
								, sql_table		: options.sql_table
								, fields		: options.fields
								, data			: data
								//, async			: false
							};

				get_server_data(request, function(data_in){
					options.data.splice($.inArray(data, options.data), 1);
					row.remove();
					_prepare_grid();

					if (options._callback) options._callback(options.data);
				});
			} else {
				options.data.splice($.inArray(data, options.data), 1);
				row.remove();
				_prepare_grid();

				if (options._callback) options._callback(options.data);
			}
		});
		
		if (typeof(on_done) === "function") on_done();
	}

	function _update_item(data, on_done){
		ret = true;

		if (false == validate_data(data)){
			return;
		}
		
		pk = null;
		$(options.fields).each(function(){
			if (this.primary_key == true){
				pk = this.name;
			}
		});

		if (!table || options.type == "edit"){
			if (typeof on_done == "function") on_done(data);
			return; 
		}

		function __update_item_ex(row, data){
			//NOW UPDATE THE MAIN LIST
			var old_data = row.prop("row_data");
			$(options.data).each(function(){
				var d = this;
				if (pk != null && d[pk] == data[pk]){
					$(options.fields).each(function(){
						if (this.name in data){
							d[this.name] = data[this.name];
						}
					});
					
					data = d;
					
				} else { //NO PK SO WE COMPARE EVERY FIELD IN THE ROW.
					var found = true; //ASSUME THE ROW IS FOUND
					
					for(var index in old_data){
						if (old_data[index] != d[index])
							found = false;
					}
					
					if (true == found){
						$(options.fields).each(function(){
							if (this.name in data){
								d[this.name] = data[this.name];
							}
						});
						
						data = d;
					}
				}
			});
			
			$(data).each(function(){
				d = this;
				$(row).find("input[type=checkbox]").removeAttr("checked");
				$(row).find("td:gt(0)").each(function(){
					if (typeof this.field.name !== "undefined")
						var name = this.field.name;
						if (typeof this.field.alias !== "undefined") name = this.field.alias;
						$(this).html(_get_grid_field_value(this.field, d[name]));
				});
			});
			
			if (typeof on_done == "function") on_done(data);
			
		}

		//UPDATE THE ROW THAT IS STILL HIGHLIGHTED
		table.find("tr td input:checked").each(function(){
			var update_row = false;
			var row = $(this).parents("tr:first");

			if (options.ajax_url && options.ajax_url != null){
				var request = {
								  server_call	: options.server_call_update
								, ajax_url		: options.ajax_url
								, sql_table		: options.sql_table
								, async			: false
								, fields		: options.fields
								, data			: data
							};

				get_server_data(request, function(data){
					__update_item_ex(row, data);
				});
			} else {
				__update_item_ex(row, data)
			}
		});
	}

	function _get_grid_field_value(field, value){
		var result = value;

		switch(field.data_type){
			case "boolean":
				result = (value == 1 ? "Y" : "");
				break;
		}

		if (typeof options.ajax_url === "undefined" || options.ajax_url == null || $.trim(options.ajax_url) == ""){
			if (field.data_type == "lookup"){
				//WITH NO URL, IT MEANS WE NEED TO TRANSLATE THE SELECTED ID INTO A NAME
				var fk = field.foreign_key;
				if (fk){ //JUST IN-CASE THE FOREIGN KEY WAS NOT SET
					if (fk.sql_table in cache){
						var data = cache[fk.sql_table];
						$(data).each(function(){
							if ((fk.value in this) && (this[fk.key] == value)){
								result = this[fk.value];
							}
						});
					}
				}
			}
		}
		
		if (result && typeof result === "string") result = result.replace(/(\n)/g, "<br/>");
		if (result == null) result = "";
		return result;
	}

	function _get_field_default_value(field){
		value = null;
		if (field.name == "group"){
			field.default_value = "system.group";
		}
		
		if (field.default_value){
			switch(field.default_value){
				case "system.user":
					value = user_credentials.id;
					break;
				case "system.date":
					value = $.format.date(new Date(), "yyyy-MM-dd HH:mm:ss");
					break;
				case "system.group":
					value = cache.subscription;
					break;
				default:
					value = field.default_value;
			}
		}

		return value;
	}

	function _format_date_fields(context){
		context.find(".widget-datepicker").not(".hasDatePicker").datepicker({dateFormat:"yy-mm-dd"});
		context.find(".widget-colorpicker").each(function(){
			obj = $(this);
			$(this).ColorPicker({
				eventName: "click"
				, color: obj.val()
				, livePreview: true
				, flat: true
				, onSubmit: function(hsb, hex, rgb, el) {
					$(el).val("#"+hex);
					$(el).ColorPickerHide();
				}
				, onBeforeShow: function () {
				}
				, onChange:  function (hsb, hex, rgb) {
					obj.val("#"+hex);
				}
			})
		});
		
		context.find(".editor").jqte();
	}

	function _build_foreign_key(context, field){
		//VERY CUSTOM CODE :-(
		if (field.name == "group_id" && typeof field.default_value == "undefined") field.default_value = "system.group";
		//END OF VERY CUSTOM CODE :-)

		if (typeof field.default_value == "undefined") field.default_value = null;

		function __build_select(field, data){
			if (typeof field.sort_order !== "undefined"){
				if ($.trim(field.sort_order.toLowerCase()) == "asc"){
					data.sort(function(a,b){
						return a[field.foreign_key.value].localeCompare(b[field.foreign_key.value]);
					});
				} else if ($.trim(field.sort_order.toLowerCase()) == "desc"){
					data.sort(function(a,b){
						return b[field.foreign_key.value].localeCompare(a[field.foreign_key.value]);
					});
				}
			}
			
			select_field = context.find("#"+field.name);
			select_field.append("<option>");
			$(data).each(function(){
				//console.log(this);
				selected = "";
				if (field.default_value){
					value = _get_field_default_value(field);
					if (this[field.foreign_key.key] == value)
						selected = "selected";
				}
				select_field.append("<option "+
								selected +
								" value='"+
								this[field.foreign_key.key]+
								"'>"+
								this[field.foreign_key.value]+
								"</option>");
				//select_field.find("option:last").val(this[field.foreign_key.key]);
			});
		}

		var skip_ajax = false;

		if (field.foreign_key.sql_table in cache){
			data = cache[field.foreign_key.sql_table];
			skip_ajax = true;
		} else {
			switch(field.default_value){
				case "system.group":
					//FIRST CHECK IF THE SELECTED SUBSCRIPTION IS IN THE CACHE
					var found = false;
					$(cache.client_list).each(function(){
						if (this.id == cache.defualt_client) found = true;
					});
					if (true == found){
						data = cache.client_list;
						skip_ajax = true;
					}
					break;
			}
		}

		if (false == skip_ajax && options.ajax_url && options.ajax_url != null){
			fk_fields = [
					  {name: field.foreign_key.key}
					, {name: field.foreign_key.value}
				];
			request = {
				  sql_table		: field.foreign_key.sql_table
				, ajax_url		: "lookup_tables.php"//options.ajax_url
				, fields		: fk_fields
				, server_call	: "lookup_read"//options.server_call_list
				};

			get_server_data(request, function(data){
				__build_select(field, data);
			});
		}
		else
			__build_select(field, data);
	}

	function _format_table(table){
		table = $(table);
		if (table.hasClass("has-stripes"))
			table.find("tbody tr:odd").addClass("table-stripe");

		var thead = table.children("thead");
		if (thead){
			thead.addClass("ui-widget ui-widget-header");
		}
		
		var tbody = table.children("tbody");
		if (tbody){
			tbody.addClass("ui-widget");
		}

		tbody.find("tr")
			.hover(
				function(){
					$(this).addClass("ui-state-highlight");
					$(this).css("cursor", "pointer");
				}
				, function(){
					$(this).removeClass("ui-state-highlight");

					$(this).css("cursor", "default");
				}
			);
	}
	
	function _create_form_input(field, with_primary_key){
		//if (typeof field.show_on_editor !== "undefined"){
			//if (field.show_on_editor == false) return "";
		//}

		if (field.primary_key == true){
			if (with_primary_key == undefined || with_primary_key == false)
				return "";
		}
		
		name = field.name;
		if (typeof field.alias !== "undefined" && $.trim(field.alias) != "" && field.alias != null){
			name = field.alias;
		}
		
		var result = "<div class='fd-widget' style='display:inline-block;width:100%;padding-bottom:5px;'>";
		result += "<div class='label fd-widget-label'>"+field.title+"</div>";
		result += "<div class='fd-widget-control'>";
		
		var data_type = $.trim(field.data_type).toLowerCase();

		if (data_type == "date" || data_type == "datetime")
			result += "<input type='text' id='"+name+"' class='form_data widget-datepicker' />";
		else if (data_type == "boolean")
			result += "<input type='checkbox' id='"+name+"' class='form_data ui-widget' />";
		else if (data_type == "number")
			result += "<input type='number' id='"+name+"' class='form_data ui-widget' />";
		else if (data_type == "color")
			result += "<p id='"+name+"' class='form_data widget-colorpicker'></p>";
		else if (data_type == "lookup")
			result += "<select id='"+name+"' class='form_data ui-widget' style='max-width:250px;' />";
		else if (data_type == "notes")
			result += "<textarea id='"+name+"' class='form_data ui-widget notes' style='width:250px;height:80px;'></textarea>";
		else if (data_type == "editor")
			result += "<textarea id='"+name+"' class='form_data ui-widget editor' style='width:250px;height:80px;'></textarea>";
		else if (data_type == "password")
			result += "<input type='password' id='"+name+"' class='form_data ui-widget' />";
		else
			result += "<input type='text' id='"+name+"' class='form_data' />";
		
		result += "</div></div>";
		
		return result;
	}

	function _build_ui_groups(){
		var main_ui_group = $('<div style="display:inline-block;width:100%">');
		if (typeof options.ui_groups === "undefined")
			options.ui_groups = [];
		
		$(options.fields).each(function(){
			var field = this;
			var found = false;
			$(options.ui_groups).each(function(){
				if (this.name == field.ui_group)
					found = true;
			});
			if (false == found && (typeof field.ui_group !== "undefined"))
				options.ui_groups.push({"name":field.ui_group});
		});
		
		$(options.ui_groups).each(function(){
			var caption = this.name
			if (this.name == "__MAIN__") caption = "";
			var grp_id = this.name.replace(/ /g, "_");
			var grp_ui = $('<div style="display:inline-block;width:99%;" id="'+grp_id+'" class="ui-panel">')
							.appendTo(main_ui_group);
			var hdr = $('<div style="display:inline-block;">').appendTo(grp_ui);
			//var btn = $("<span class='ui-icon ui-icon-triangle-1-s' style='cursor:pointer;float:left'>");
			var title = $("<span style='float:left;'>").html(caption);
			
			if (caption != ""){
				hdr/*.append(btn)*/.append(title);
				hdr.addClass("ui-widget-header");
			}
			
			if (caption != "")
				grp_ui.addClass("ui-border-all");

			var content = $('<div style="display:inline-block;width:100%;height:99%;">').appendTo(grp_ui);
			var panel = $('<div class="left-hand-panel fieldset" style="width:49%;height:100%;float:left;padding:0;margin:0;">').appendTo(content);
			var panel = $('<div class="right-hand-panel fieldset" style="width:49%;height:100%;float:right;padding:0;margin:0;">').appendTo(content);
			
			if (this.name == "__MAIN__"){
				grp_ui.css("border", "0");
			}
		});

		return main_ui_group;
	}

	function _prepare_grid(){
		if (!table) return;
		var _dlg = table.parents(".widget-content");
		
		if (options.toolbar.indexOf("update") !== -1){
			table.find("tbody tr").unbind("dblclick").dblclick(function(){
				$(this).parents("table").find("td input[type=checkbox]").removeAttr("checked");
				$(this).find("td input[type=checkbox]").attr("checked", "checked");
				//_create_update_dlg($(this));
				$(options.content_area).find(".fd-lookup-table #btn_update").trigger("click");
			});
		}
		_format_table(table);
	}

	function add_row_to_grid(data){
		//UPDATE THE GRID
		if (!table){
			console.log("No grid to update");
			return;
		}
		
		$(data).each(function(){
			var row = this;
			var tr = $("<tr style='text-align:center'>")
						.prop("row_data", this)
						.appendTo(table);

			td = $("<td>")
					.append("<input type='checkbox' class='ui-widget' />")
					.prop("field",{})
					.appendTo(tr);

			$(options.fields).each(function(){
				if (this.show_on_grid != false){
					var value = row[this.name];
					if (typeof this.alias !== "undefined"){
						if (this.alias in row) value = row[this.alias];
					}
					var td = $("<td>")
								.html(_get_grid_field_value(this, value))
								.prop("field", this)
								.appendTo(tr);
					
					if (this.css_style && $.trim(this.css_style) !== ""){
						td.attr("style", td.attr("style")+";"+this.css_style);
					}
				}
			});
		});
		
		_prepare_grid();
	}

	function _crud_init_dialog(context, data){
		//console.log(data);
		//NOW DO THE FOREIGN-KEY FIELDS
		$(options.fields).each(function(){
			if (this.foreign_key){
				_build_foreign_key(context, this);
			}

			if (this.readonly && this.readonly == true){
				if (this.data_type != "lookup"){
					context.find("#"+this.name).attr("readonly", "readonly");
				}
				else{
					context.find("#"+this.name).attr("disabled", "disabled");
				}
			}

			var value = _get_field_default_value(this);
			if (this.data_type == "boolean"){
				if (parseFloat(value) == 1 || value === true)
					context.find("#"+this.name).prop("checked", true);
			}
			else if (this.data_type != "lookup")
				context.find("#"+this.name).val(unescape(value|| "" ));
			
			if (this.primary_key == true)
				context.find("#"+this.name).attr("readonly", true);
		});
		
		//CLEAR THE FIELDS
		context.find(".form_data").each(function(){
			if (this.tagName !== "SELECT"){
				$(this).val("");
			} else if (this.type == "checkbox"){
				this.checked = false;
			}
		});
		
		_format_date_fields(context);
		
		//INITIALISE FIELDS WITH DATA PROVIDED
		if (!data) return;
		
		context.find(".form_data").each(function(){
			//IF ID IS NOT IN OBJECT THEN JUMP OUT
			if (!(this.id in data)) return;
			
			var value = data[this.id] || "";
			
			if (this.type == "checkbox"){
				this.checked = (parseFloat(value) == 1);
			
			} else if (this.tagName == "SELECT") {
				$(this).find("option").each(function(){
					if ($(this).val() == value){
						$(this).attr("selected", "selected");
					}
					else
						$(this).removeAttr("selected");
				});
			
			} else {
				$(this).val(unescape(value.replace(/<br>/g,"\n")));
			}
		});
	}
	
	function _create_entry_screen(){
		var _dlg = $("<div class='fd-lookup-table widget-content' title='"+options.title+"' >");
		
		var $toolbar = $('<div class="ui-widget-header" style="width:100%;vertical-align:middle;display:inline-block;">').appendTo(_dlg);

		$toolbar.append('<div id="tb_buttonset" style="float:left">\
					<button id="btn_create" data-icon="ui-icon-plusthick">Create</button>\
					<button id="btn_update" data-icon="ui-icon-pencil">Update</button>\
					<button id="btn_import" data-icon="ui-icon-arrowreturnthick-1-s">Import</button>\
					<button id="btn_export" data-icon="ui-icon-arrowreturnthick-1-n">Export</button>\
					<button id="btn_remove" data-icon="ui-icon-closethick">Remove</button>\
				</div>');
		$toolbar.find("#tb_buttonset").buttonset();
		
		$toolbar.find("#tb_buttonset button").each(function(){
			$(this).css({"border":"none"}).button({
				  text: false
				, icons:{primary:$(this).attr("data-icon")}
			});
		});
		
		if (options.toolbar.indexOf("create") == -1){
			$toolbar.find("#btn_create").hide();
		}
		
		if (options.toolbar.indexOf("remove") == -1){
			$toolbar.find("#btn_remove").hide();
		}
		
		if (options.toolbar.indexOf("update") == -1){
			$toolbar.find("#btn_update").hide();
		}
		
		if (options.toolbar.indexOf("import") == -1){
			$toolbar.find("#btn_import").hide();
		}
		
		if (options.toolbar.indexOf("export") == -1){
			$toolbar.find("#btn_export").hide();
		}
		
		$toolbar.append('<div style="float:left;vertical-align:middle;" class="btn-search">\
						<label style="width:50px;">Search: </label>\
						<input type="text" id="search_string" class="form_data text ui-widget-content ui-corner-all" />\
				</div>');
		
		if (options.toolbar.indexOf("search") == -1){
			$toolbar.find(".btn-search").hide();
		}
		
		_dlg.find("#search_string").keyup(function(){
				var find_me = $.trim($(this).val().toLowerCase());
				var find_list = find_me.split("+");
				for(var i = 0; i < find_list.length; i++){
					find_list[i] = $.trim(find_list[i]);
				}
				var tbody = _dlg.find("table tbody");
				tbody.find("tr").each(function(){
					var found = true;	//ASSUME THE ROW CAN BE SHOWN.
					var tr = $(this);
					tr.show();
					
					//FIND ALL MATCHES
					for(var i = 0; i < find_list.length; i++){
						if (find_list[i] == "") continue;
						if (find_list[i][0] == "!") continue;
						
						found = false;	//ASSUME IT IS NOT THERE
						tr.find("td").each(function(){
							value = $.trim($(this).text().toLowerCase());
							if (find_list[i] !== "" && find_list[i][0] != "!"){
								if (value.indexOf(find_list[i]) !== -1){
									found = true;
								}
							}
						});
						
						if (false == found) break;
					}

					//FIND ALL NOT(!)-MATCHES
					for(var i = 0; i < find_list.length; i++){
						if (find_list[i] == "") continue;
						if (find_list[i][0] != "!") continue;
						
						var find_me2 = $.trim(find_list[i].substr(1));

						tr.find("td").each(function(){
							value = $.trim($(this).text().toLowerCase());
							if (find_me2 != "" && value.indexOf(find_me2) >= 0){
								tr.hide();
							}
						});
					}

					if (false == found && find_me != ""){
						tr.hide();
					}
				});
			});

		//TOOLBAR
		$toolbar.find("#btn_update").unbind("click").click(function(){
			var tr		= null;
			var cnt		= table.find("tr td input[type=checkbox]:checked").length;

			if (cnt == 0){
				alert("Nothing was selected.");
				return;
			}
			else if (cnt != 1){
				alert("Please only select one item");
				return;
			}

			tr = table.find("tr td input[type=checkbox]:checked").first().parents("tr");
			_create_update_dlg(tr);
		});

		$toolbar.find("#btn_import").unbind("click").click(function(){
			var opts = $.extend(true, {}, options);
			opts.event_name = null;
			$().import_data(opts, function(data){
				//NEED TO FAKE THE PRIMARY/AUTO-NUMBER FIELD
				var pk = null;
				var max = 0;
				$(options.fields).each(function(){
					if (this.primary_key == true) pk = this.name;
				});
				if (pk != null){
					$(options.data).each(function(){
						if (parseFloat(this[pk]) > max) max = parseFloat(this[pk]);
					});
					max++;
					data[pk] = max;
				}
				
				options.data.push(data);
				if (typeof options._callback == "function"){
					options._callback(options.data);
				}
			});
		});

		$toolbar.find("#btn_export").unbind("click").click(function(){
			var table	= _dlg.find("table");
			var header	= "";
			var data	= "";
			table.find("thead tr").each(function(){
				if (header.length != 0) header += "\r\n";
				var start = true;
				$(this).find("th").each(function(){
					if (true == start){
						start = false;
						header += '"'+$(this).text()+'"';
					} else {
						header += ',"' + $(this).text()+'"';
					}
				});
			});
			table.find("tbody tr").each(function(){
				if ($(this).is(":visible") !== true) return;
				
				if (data.length != 0) data += "\r\n";
				var start = true;
				$(this).find("td").each(function(){
					if (true == start){
						start = false;
						data += '"'+$(this).text()+'"';
					} else {
						data += ',"' + $(this).text()+'"';
					}
				});
			});
			
			var text = /*header+"\r\n"+data;*/ "<table>"+ _dlg.find("table").html() + "</table>";
			
			var $dlg = $("<div title='Export Data'>");
			$dlg.dialog({ autoOpen: false,width: 640,height: 400,modal: true,resizable: true,draggable: true });
			var $txt = $("<textarea style='width:100%;height:99%'>").appendTo($dlg);
			$txt.val(text);
			$dlg.dialog("open");
		});

		$toolbar.find("#btn_remove").unbind("click").click(function(){
			_remove_item(function(){
				$(options.content_area).find(".fd-lookup-create, .fd-lookup-update").hide();
				$(options.content_area).find(".fd-lookup-table").show();
			});
		});

		return _dlg;
	}

	function _create_new_dlg(){
		var ui_group = _create_form();

		var _dlg = $("<div title='"+options.title+" - Create New' class='fd-lookup-create'>");
		
		var $toolbar = $('<div class="ui-widget-header" style="width:100%;vertical-align:middle;display:inline-block;">').appendTo(_dlg);
		
		_dlg.append(ui_group);
		
		$toolbar.append('<div id="tb_buttonset" style="float:left">\
							<button id="btn_create" data-icon="ui-icon-disk">Save</button>\
							<button id="btn_cancel" data-icon="ui-icon-cancel">Cancel</button>\
						</div>');
		
		$toolbar.find("#tb_buttonset button").each(function(){
			$(this).css({"border":"none"}).button({
				text: false
				, icons:{primary:$(this).attr("data-icon")}
			});
		});
		
		$toolbar.find("#tb_buttonset").buttonset();
		
		$toolbar.find("#btn_create").click(function(){
			console.log("lookup_forms::btn_create::click");
			data = {};
			$(options.fields).each(function(){
				var name = (!this.alias ? this.name : this.alias);
				if (typeof this.default_value !== "undefined"){
					data[name] = _get_field_default_value(this);
				} else {
					data[name] = null;
				}
			});

			$(this).parents(".fd-lookup-create").find(".form_data").each(function(){
				if (this.type == "checkbox")
					data[this.id] = ($(this).is(":checked") ? 1 : 0);
				else
					data[this.id] = $(this).val();
			});
			
			_create_item(data, function(data){
				add_row_to_grid(data);
				$(options.content_area).find(".fd-lookup-create #btn_cancel").trigger("click");
			});
		});
		
		return _dlg;
	}

	function _create_update_dlg(src_row){
		var ui_group = _create_form();
		
		var _dlg = $("<div title='"+options.title+" - Update Existing' class='fd-lookup-update'>");
		var $toolbar = $('<div class="ui-widget-header" style="width:100%;vertical-align:middle;display:inline-block;">').appendTo(_dlg);

		$toolbar.append('<div id="tb_buttonset" style="float:left">\
					<button id="btn_update" data-icon="ui-icon-disk">Save</button>\
					<button id="btn_cancel" data-icon="ui-icon-cancel">Cancel</button>\
					<button id="btn_remove" data-icon="ui-icon-closethick">Remove</button>\
					<button id="btn_clone" data-icon="ui-icon-plusthick">Clone as New</button>\
				</div>');

		$toolbar.find("#tb_buttonset button").each(function(){
			$(this).css({"border":"none"}).button({
				text: false
				, icons:{primary:$(this).attr("data-icon")}
			});
		});
		
		$toolbar.find("#tb_buttonset").buttonset();

		$toolbar.find("#btn_clone")
				.button("option", "text", true)
				.click(function(){
					data = {};
					$(options.fields).each(function(){
						var name = (!this.alias ? this.name : this.alias);
						if (typeof this.default_value !== "undefined"){
							data[name] = _get_field_default_value(this);
						} else {
							data[name] = null;
						}
					});

					_dlg.find(".form_data").each(function(){
						if (this.type == "checkbox")
							data[this.id] = ($(this).is(":checked") ? 1 : 0);
						else
							data[this.id] = $(this).val();
					});

					_create_item(data, function(data){
						add_row_to_grid(data);
						$(options.content_area).find(".fd-lookup-create #btn_cancel").trigger("click");
					});
				});
		
		$toolbar.find("#btn_remove").click(function(){
			$(options.content_area).find(".fd-lookup-table #btn_remove").trigger("click");
		});
				
		$toolbar.find("#btn_update").click(function(){
			//BUILD THE DATA TO PASS BACK
			data = {};
			if (src_row){
				var row_data = src_row.prop("row_data");

				$(row_data).each(function(){
					var row = this;
					$(options.fields).each(function(){
						var name = (this.alias ? this.alias : this.name);
						data[name] = row[name];
					});
				});
			}

			_dlg.find(".form_data").each(function(){
				if (this.type == "checkbox")
					data[this.id] = ($(this).is(":checked") ? 1 : 0);
				else
					data[this.id] = $(this).val();
			});
			
			for(var index in data){
				$(options.fields).each(function(){
					var name = (this.alias ? this.alias : this.name);
					if (name == index){
						this.default_value = data[index];
					}
				});
			}
			_update_item(data, function(data){
				_dlg.find("#btn_cancel").trigger("click");
				if (options._callback) {
					options._callback(data);
				}
			});
		});

		_dlg.append(ui_group);

		if (options.toolbar.indexOf("clone") === -1)
			$toolbar.find("#btn_clone").hide();
		
		if (options.toolbar.indexOf("remove") === -1)
			$toolbar.find("#btn_remove").hide();
			
		//ADD THE "LINK" BUTTON TO THE BOTTOM OF THE SCREEN
		var div = $("<div>").addClass("ui-border-top").appendTo(_dlg);
		div.css({
			  position		: "relative"
			, bottom		: 0
			
			, width			: "100%"
			//, height		: "50px"
			, display		: "inline-block"
		});
		
		//DIALOG LINKS
		$(options.links).each(function(){
			var $this = this;
			var btn = $("<button>")
						.appendTo(div)
						.text($this.reference.title)
						.button()
						.css({
								"float"		: "right"
							})
						.click(function(){
							//FIND THE SELECTED RECORD ON THE MAIN GRID
							var row = table.find("td input[type=checkbox]:checked");
							if (row.length == 0){
								console.log("nothing was selected");
								return;
							} else if (row.length > 1) {
								alert("Only one record can be selected at a time");
								return;
							}
							row = row.parents("tr");
							var ref = $this;

							$this.reference.eventName = null;
							if (options.ajax_url == null) $this.reference.ajax_url = null;
							
							var objx = $.extend(true, {}, $this.reference);
							var data  = [];
							
							//MAP FIELDS
							$($this.mapping).each(function(){
								//DON'T FEEL LIKE DOING IT NOW.....22 JUNE 2013
								var src_field	= row.prop("row_data");
								var dest_field	= null;
								var map			= this;

								$($this.reference.fields).each(function(){
									if (map.destination == this.name){
										dest_field = this;
									}
								});
								if (src_field != null && dest_field != null){
									dest_field.default_value = src_field[map.source];
									
									//NOW ONLY COPY DATA THAT RELATES TO THE OPEN RECORD.
									$(objx.data).each(function(){
										if (this[map.destination] == src_field[map.source])
											data.push(this);
									});
								}
							});
							
							objx.data		= data;
							objx.toolbar	= ["search"];
							$().lookup_form(objx);
						});
		});

		return _dlg;
	}

	function _create_data_table(data){
		var div = $("<div style='display:inline-block;max-height:450px;width:100%;overflow:auto;'>");
		table = $("<table border=0 style='width:100%;' class='has-stripes'>").appendTo(div);
		var tr = $("<tr>").addClass("ui-widget-header");
		table.append($("<thead>").append(tr));
		tr.append("<th><input type='checkbox' class='ui-widget'/></th>"); //THIS IS FOR THE CHECKBOX
		$(options.fields).each(function(){
			if (this.show_on_grid == false) return;

			var th = $("<th>")
					.html(this.title)
					.prop("field", this)
					.appendTo(tr);
		});
		
		table.find("thead tr th input[type=checkbox]").unbind("click").click(function(){
			if (true == this.checked){
				tbody.find("tr:visible td input[type=checkbox]").attr("checked", "checked");
			}
			else{
				tbody.find("td input[type=checkbox]").removeAttr("checked");
			}
			
		});
		
		var tbody = $("<tbody style='overflow-y: auto; overflow-x:auto;height:200px;width:400px;'>");
		table.append(tbody);
		
		options.data = data;
		$(options.data).each(function(){
			var tr = $("<tr style='text-align:center;'>")
						.prop("row_data", this)
						.appendTo(tbody);

			td = $("<td>")
					.append("<input type='checkbox' class='ui-widget' />")
					.prop("field",{})
					.appendTo(tr);
			
			var row = this;
			$(options.fields).each(function(){
				if (this.show_on_grid == false) return;

				var name = this.name;
				if (typeof this.alias !== "undefined") name = this.alias;

				var td = $("<td>")
						.html(_get_grid_field_value(this, row[name]))
						.prop("field", this)
						.appendTo(tr);
						
				if (this.css_style && $.trim(this.css_style) != ""){
					td.attr("style", td.attr("style")+";"+this.css_style);
				}
			});
		});

		_prepare_grid();

		return div;
	}
	
	function show_home_panel(){
		if (["edit", "create"].indexOf(options.type) == 0){
			if (true == options.use_dialog){
				options.content_area.dialog("close");
			} else {
				console.log("Do nothing for now.....might remove the panel at some other point...if needed");
			}
			
		} else {
			options.content_area.find(".fd-lookup-create").hide(options.effect);//, {direction: "right"}, 100);
			options.content_area.find(".fd-lookup-update").hide(options.effect);//, {direction: "right"}, 100);
			
			options.content_area.find(".fd-lookup-table").show(options.effect);
		}
	}
	
	function _create_with_data_grid(){
		//console.log("_create_with_data_grid");
		//var use_dialog		= false;
		var panel_main		= _create_entry_screen();
		var panel_create	= _create_new_dlg();
		var panel_update	= _create_update_dlg();
		
		panel_main.find("#btn_create").unbind("click").click(function(){
			panel_main.hide(options.effect);//, {direction: "down"}, 100);
			panel_update.hide(options.effect);//, {direction: "down"}, 100);
			
			_crud_init_dialog(panel_create);
			panel_create.show(options.effect);
			panel_create.find("input:first").focus();
		});
		
		panel_main.find("#btn_update").unbind("click").click(function(){
			var data = {};
			if (options.type !== "edit"){
				//GET THE ROW SELECTED
				var row = table.find("td input[type=checkbox]:checked");
				if (row.length == 0){
					alert("Nothing selected");
					return;
				}
				row = row.parents("tr");
				data = row.prop("row_data");
			} else {
				if (options.data.length == 0){
					var d = {};
					$(options.fields).each(function(){
						d[this.name] = this.default_value;
					});
					options.data.push(d);
				}
				console.log("test");
				console.log(options.data);
				data = options.data[0];
			}
			
			_crud_init_dialog(panel_update, data);
			
			panel_main.hide(options.effect);//, {direction: "down"}, 100);
			panel_create.hide(options.effect);//, {direction: "down"}, 100);

			panel_update.show(options.effect);
			panel_create.find("input:first").focus();
		});
		
		panel_update.find("#btn_cancel").unbind("click").click(function(){
			show_home_panel();
			//panel_create.hide(options.effect);//, {direction: "right"}, 100);
			//panel_update.hide(options.effect);//, {direction: "right"}, 100);
			
			//panel_main.show(options.effect);
		});
		
		panel_create.find("#btn_cancel").unbind("click").click(function(){
			show_home_panel();
			//panel_create.hide(options.effect);//, {direction: "right"}, 1000);
			//panel_update.hide(options.effect);//, {direction: "right"}, 1000);
			
			//panel_main.show(options.effect);
		});
		
		panel_main.hide();
		panel_create.hide();
		panel_update.hide();
		
		if (false == options.use_dialog){
			//FIRST CLEAR THE AREA
			$(options.content_area).children().remove();

			//NOW ADD THE CONTENT
			$(options.content_area)
				.append(panel_main)
				.append(panel_create)
				.append(panel_update);
			
		} else {
			//console.log("load the dialog");
			var _dlg = options.content_area; //$("<div class='widget-content' title='"+options.title+"'>");
			_dlg.attr("title", options.title);
			_dlg
				.append(panel_main)
				.append(panel_create)
				.append(panel_update);
			
			//DIALOG OPTIONS
			_dlg.dialog({
				  autoOpen		: false
				, height		: (options.height ? options.height : 640)
				, width			: (options.width ? options.width : 800)
				, modal			: true
				, open			: function(event, ui){}
				, close: function() {
					if (options._callback) options._callback(options.data);
				}
			});
			
			_dlg.dialog("open");
		}

		var on_open = function(data){
			switch(options.type){
				case "create":
					panel_main.find("#btn_create").trigger("click");
					break;
				case "edit":
					panel_main.find("#btn_update").trigger("click");
					break;
				default:
					panel_create.find("#btn_cancel").trigger("click");
					break;
			}
		}
		
		//DO AN AJAX CALL TO GET FRESHEST DATA
		if ((typeof options.ajax_url !== "undefined") && options.ajax_url != null && (typeof options.server_call_list !== "undefined" && options.server_call_list != null)){
			request = {
					  ajax_url		: options.ajax_url
					, server_call	: options.server_call_list
					, sql_table		: options.sql_table
					, fields		: options.fields
					//, async			: false
				};
			request = $.extend(true, {}, options, request);
			get_server_data(request, function(data){
				_dlg.append(_create_data_table(data));
				on_open();
			});
		} else {
			panel_main.append(_create_data_table(options.data));
			on_open();
		}
		
	}

	function _create_form(){
		var _dlg_fieldset = "";
		var ui_group = _build_ui_groups();
		$(options.ui_groups).each(function(){
			var grp_name	= this.name;
			var grp_id		= this.name.replace(/ /g, "_");
			
			//FIND ALL FIELDS THAT SHOULD BE IN THE PANEL
			var fields = [];
			$(options.fields).each(function(){
				if (this.ui_group == grp_name && this.show_on_editor == true){
					fields.push(this);
				}
			});
			
			var l_ul = $("<ul style='list-style:none;padding:0;'>");
			var r_ul = $("<ul style='list-style:none;padding:0;'>");
			var bool = true;
			$(fields).each(function(){
				if (options.alignment == "horizontal"){
					if (true == bool){
						l_ul.append("<li>"+_create_form_input(this)+"</li>");
					
					} else {
						r_ul.append("<li>"+_create_form_input(this)+"</li>");
					}
					bool = !bool;
				
				} else {
					l_ul.append("<li>"+_create_form_input(this)+"</li>");
				}
			});
			ui_group.find("#"+grp_id+" .left-hand-panel").append(l_ul);
			ui_group.find("#"+grp_id+" .right-hand-panel").append(r_ul);

			l_ul.sortable();
			r_ul.sortable();
			
			if (options.alignment == "vertical"){
				l_ul.find("li .fd-widget-label").css({
					  "float"		: "left"
					, "overflow"	: "clip"
					, "width"		: "25%"
					, "height"		: "auto"
				});
				l_ul.find("li .fd-widget-control").css({
					  "float"		: "right"
					, "overflow"	: "clip"
					, "width"		: "70%"
					, "height"		: "auto"
				});
				ui_group.find("#"+grp_id+" .left-hand-panel").css({"width":"100%"});
				ui_group.find("#"+grp_id+" .right-hand-panel").remove();
				
			} else {
				ui_group.find(".fd-widget").css({"padding-bottom": "5px"});
				
			}
			
			$(fields).each(function(){
				var ctrl = ui_group.find("#"+this.name);
				if (this.required && ctrl.length != 0){
					console.log("Required field");
					ctrl.parents(".fd-widget-control").addClass("mandatory");
					console.log(ctrl.parents(".fd-widget").html());
				}
			});
		});
		
		//REMOVE PANELS THAT ARE EMPTY
		ui_group.find(".ui-panel").each(function(){
			if ($(this).find(".left-hand-panel ul li").children().length == 0 &&
				$(this).find(".right-hand-panel ul li").children().length == 0){
				$(this).remove();
			}
		});
		
		//IF THERE IS ONLY A LEFT-HAND-PANEL, THEN AUTO ADJUST PANEL CONTENT TO VERTICAL
		//SO THAT IT CAN LOOK NICE
		ui_group.find(".ui-panel").each(function(){
			if ($(this).find(".right-hand-panel ul li").children().length == 0){
				$(this).find(".right-hand-panel").remove();
				$(this).find(".left-hand-panel li .fd-widget-label").css({
					  "float"		: "left"
					, "overflow"	: "clip"
					, "width"		: "25%"
					, "height"		: "auto"
				});
				
				$(this).find(".left-hand-panel").css({"width":"100%"});
				$(this).find(".fd-widget").css({"padding-bottom": "0"});
			}
		});
		
		ui_group.children("div").fd_panel();
		
		return ui_group;
	}
	
}
});
})(jQuery);
